package
{
	import flash.desktop.Clipboard;
	import flash.desktop.NativeApplication;
	import flash.desktop.NativeDragManager;
	import flash.desktop.NativeDragOptions;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.NativeWindowSystemChrome;
	import flash.display.NativeWindowType;
	import flash.display.Screen;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.utils.getDefinitionByName;
	
	import kr.as3.display.NewWindow;
	import kr.pfg.applications.captureyourscreen.clipboard.ClipboardChecker;
	import kr.pfg.applications.captureyourscreen.display.ImageWindow;
	import kr.pfg.applications.captureyourscreen.display.Intro;
	import kr.pfg.applications.captureyourscreen.events.CaptureEvent;
	import kr.pfg.applications.captureyourscreen.events.IntroEvent;
	import kr.pfg.applications.captureyourscreen.load.XMLLoader;
	import kr.pfg.applications.captureyourscreen.nativemenu.CreateNativeMenuItem;
	import kr.pfg.applications.captureyourscreen.utils.CapturedImageSaver;
	import kr.pfg.applications.captureyourscreen.utils.SystemUtil;
	import kr.pfg.socialproject.SocialProject;
	import kr.pfg.socialproject.events.LatestVersionEvent;

	public class CaptureYourScreen extends SocialProject
	{
		public function CaptureYourScreen()
		{
			this.projectName = "CaptureYourScreen";
			
			super();
			
			// 1. check latest version and resgist listeners.
			this.addEventListener( LatestVersionEvent.CHECK_VERSION, versionCheck );
			this.addEventListener( LatestVersionEvent.CHECK_VERSION_FAIL, versionCheckFail );
			this.checkLatestVersion();
			
			// 2. register listeners of components is on *.fla file.
			this.initButtons();
			
			// 3. wait a time of capture the screen when user press prtsc key.
			// this.initCaptureClipboard();
			// it moved after intro
			
			// 4. show intro
			this.initIntro();
			
			// 5. create contextMenu
			this.initContextMenu();
		}
		
		/**
		 * 1. Listeners of check version.
		 * It isn't necessary call at first, just call when it needs to.
		 */		
		
		private function versionCheck( e: LatestVersionEvent ): void
		{
			trace( "latest version is " + e.version );
			trace( "current version is " + this.currentVersion );
		}
		
		private function versionCheckFail( e: LatestVersionEvent ): void
		{
			trace( "can't check latest version because " + e.message );
		}
		
		/**
		 * 2. Register listeners of components 
		 */		
		
		private function initButtons(): void
		{
			// close, minimize, else...
		}
		
		/**
		 * 3. Wait and watch clipboard for captured image. 
		 */		
		
		private var checker:ClipboardChecker;
		private function initCaptureClipboard(): void
		{
			// addEventListener "enterframe", and get a bitmapdata from clipboard.
			this.checker = new ClipboardChecker();
			this.checker.addEventListener( CaptureEvent.CAPTURE_SUCCESS, this.captureSuccessHandler );
			this.checker.start();
		}
		
		/**
		 * When CaptureEvent dispatch, this function start to work a next things.
		 */
		private var capturedBmd:BitmapData;
		private var captureFileClipboard:Clipboard;
		private function captureSuccessHandler( e:CaptureEvent ):void
		{
			this.showSmallImage();
			this.capturedBmd = e.captured;
			
			// 1. basic screen process.
			new ImageWindow( this.capturedBmd ); 
			// wooyaggo : do when captured
			// this.saveAsJPG();
			
			// 2. full screen process.
			//new FullScreenImageWindow( this.capturedBmd );
		}
		
		/**
		 * Then temparary save it right away.
		 */ 
		
		private function saveAsJPG():void
		{
			this.captureFileClipboard = CapturedImageSaver.getToSaveAsJPGClipboard( this.capturedBmd, "image.jpg" );
		}
		
		/**
		 * show a small image and hide a small image.
		 */
		 
		 private var smallImage:Sprite;
		 private function showSmallImage():void
		 {
		 	if( !this.smallImage )
		 	{
		 		this.smallImage = new Sprite();
		 		this.stage.addChild( this.smallImage );
		 	}
		 	
		 	var dragIcon:Bitmap = new Bitmap( this.loadBmpAssets( "icon" ) );
		 	if( this.smallImage.numChildren == 0 )
		 		this.smallImage.addChild( dragIcon );
		 		
		 	this.smallImage.buttonMode = true;
			this.smallImage.addEventListener( MouseEvent.MOUSE_DOWN, this.dragSmallIamge );
		 }
		 
		 private function hideSmallImage():void
		 {
		 	if( this.smallImage.numChildren != 0 )
		 		this.smallImage.removeChildAt( 0 );
		 }
		 
		/**
		 * It help you can drag icon to outside, then create a JPG file.
		 */
		
		 private function dragSmallIamge( e:MouseEvent ):void
		 {
		 	this.hideSmallImage();
		 	
		 	var dragIcon:BitmapData = this.loadBmpAssets( "icon_add" );
		 	
		 	var options:NativeDragOptions = new NativeDragOptions();
		 	options.allowCopy = false;
		 	options.allowLink = false;
		 	
		 	NativeDragManager.doDrag( this.smallImage, this.captureFileClipboard, dragIcon, null, options );
		 }
		 
		/**
		 * Get library bitmap assets
		 */  
		 
		 private function loadBmpAssets( name:String ):BitmapData
		 {
		 	var referClass:Class = getDefinitionByName( name ) as Class;
		 	var bmd:BitmapData = new referClass( -1, -1 );
		 	
		 	return bmd;
		 }
		 
		private var introWindow: NewWindow;
		private var intro: Intro;
		/**
		 * 4. Initialize Intro each by OS.
		 */
		private function initIntro(): void
		{
			this.intro = new Intro();
			//intro image alpha
			this.intro.alpha = .7;
			
			var screenBound: Rectangle = Screen.mainScreen.visibleBounds;
			
			this.introWindow = new NewWindow( NativeWindowType.UTILITY, NativeWindowSystemChrome.NONE, true );
			this.introWindow.width = this.intro.width;
			this.introWindow.height = this.intro.height;
			this.introWindow.x = ( screenBound.width - this.introWindow.width ) / 2;
			this.introWindow.y = ( screenBound.height - this.introWindow.height ) / 2;
			this.introWindow.stage.addChild( this.intro );
			this.introWindow.activate();
			this.introWindow.alwaysInFront = true;
			
			this.intro.addEventListener( IntroEvent.END_INTRO, introComplete );
		}
		
		private function introComplete( e: IntroEvent ): void
		{
			this.introWindow.stage.removeChild( this.intro );
			this.introWindow.close();
			this.introWindow = null;
			this.intro = null;
			
			this.initCaptureClipboard();
		}
		
		/**
		 * Get application's current version from descriptor. Not a latest version. 
		 */		
		
		private var _currentVersion: String;
		private function get currentVersion(): String
		{
			if( this._currentVersion == null )
			{
				var descriptor: XML = XML( NativeApplication.nativeApplication.applicationDescriptor );
				var ns: Namespace = descriptor.namespace();
				this._currentVersion = descriptor.ns::version.toString();
			}
			
			return this._currentVersion;
		}
		private function initContextMenu(): void
		{
			var xmlLoader: XMLLoader = new XMLLoader( "./kr/pfg/applications/captureyourscreen/load/xmlAssets/contextMenu.xml" );
			var xml: XML = xmlLoader.getResult();
			trace( xml );
			var contextMenu: CreateNativeMenuItem = new CreateNativeMenuItem( xml );
			var os: String = SystemUtil.clientOS();
			if( os == "win" )
			{
				stage.nativeWindow.menu = contextMenu;
			}
			else
			{
				NativeApplication.nativeApplication.menu = contextMenu;
			}
		}
	}
}
